package br.usp.ime.dojo.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class Chat extends Composite {
	private final int REFRESH_TIME = 1000;
	private TextArea chatViewerTA;
	private TextBox chatWriterTB;
	private Button submitBTN;
	private VerticalPanel panel;
	private HorizontalPanel textBoxAndSendHP;
	private ChatServiceAsync chatSvc;
	private String user = "";
	private String room = "";
	private Label chatTitleLBL;
	Timer timerUpdateMessages;

	public Chat(String name, String roomName) {
		user = name;
		room = roomName;

		createInterface();

		chatSvc = GWT.create(ChatService.class);

		chatSvc.createChatRoom(room, new AsyncCallback<Void>() {
			public void onFailure(Throwable caught) {
			}

			public void onSuccess(Void nul) {
				chatSvc.registerUser(user, room, new AsyncCallback<Void>() {
					public void onFailure(Throwable caught) {
					}

					public void onSuccess(Void nul) {

					}

				});
			}
		});
		setInterfaceVisual();
		initWidget(panel);
	}

	private void setInterfaceVisual() {
		chatViewerTA.setReadOnly(true);
		chatViewerTA.setWidth("100%");
		chatWriterTB.setWidth("100%");
		chatViewerTA.setVisibleLines(8);

		textBoxAndSendHP.setWidth("100%");
		panel.setHeight("100%");
		panel.setWidth("100%");

		panel.add(chatTitleLBL);
		panel.add(chatViewerTA);

		textBoxAndSendHP.add(chatWriterTB);
		textBoxAndSendHP.add(submitBTN);

		panel.add(textBoxAndSendHP);
	}

	private void createInterface() {
		panel = new VerticalPanel();
		textBoxAndSendHP = new HorizontalPanel();

		chatViewerTA = new TextArea();
		chatWriterTB = new TextBox();
		submitBTN = new Button("Send");
		chatTitleLBL = new Label("Chat Area");

		createListeners();

		timerUpdateMessages = new Timer() {
			public void run() {
				updateMessages();
			}
		};

		timerUpdateMessages.scheduleRepeating(REFRESH_TIME);
	}

	private void createListeners() {
		submitBTN.addClickHandler(new ClickHandler() {

			public void onClick(ClickEvent event) {
				send();
			}
		});

		chatWriterTB.addKeyDownHandler(new KeyDownHandler() {

			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					send();
				}
			}
		});
	}

	private void send() {

		AsyncCallback<String> callback = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
			}

			public void onSuccess(String result) {
				chatWriterTB.setText("");
				chatViewerTA.getElement().setScrollTop(chatViewerTA.getElement().getScrollHeight());
			}
		};

		chatSvc.sendMessage(user, room, chatWriterTB.getText(), callback);
	}

	private void updateMessages() {

		AsyncCallback<String> callback1 = new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {

			}

			public void onSuccess(String result) {
				if (result.compareTo("") != 0) {
					chatViewerTA.setText(chatViewerTA.getText() + result);
					chatViewerTA.getElement().setScrollTop(chatViewerTA.getElement().getScrollHeight());
				}
			}
		};

		chatSvc.checkNewMessages(user, room, callback1);
	}
	public void cancel() {
		timerUpdateMessages.cancel();
	}
}